/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package programs;

import columnar.BitmapIndexScan;
import columnar.Columnarfile;
import diskmgr.PCounter;
import global.AttrOperator;
import global.AttrType;
import global.IndexType;
import heap.Tuple;
import iterator.ColumnarBitmapEquiJoins;
import iterator.ColumnarFileScan;
import iterator.CondExpr;
import iterator.FldSpec;
import iterator.RelSpec;

/**
 *
 */
public class ColumnBitmapJoinTest {

    private static short REC_LEN_STRING = 160;
    private static short REC_LEN_INT = 32;

    private static Columnarfile lcf = null;
    private static Columnarfile rcf = null;
    private static String columnDBName = "";
    private static String leftColumnarFileName = "";
    private static String rightColumnarFileName = "";
    private static int leftColumnNo = 0;
    private static int rightColumnNo = 0;
    private static String[] projectionList = null;
    private static int no_outFields = 0;
    private static int mSize = 1;
    private static boolean reCreateIndexes = false;

    public static void main (String [] args) throws Exception
    {
        args = new String[9];
        args[0]= "ColumnDB2";
        args[1]= "ColumnarFile1";   //Name of the leftColumnarFileName
        args[2]= "2";              //Name of the column to join from the Left Columnarfile
        args[3]= "ColumnarFile2";   //Name of the rightColumnarFileName
        args[4]= "2";             //Name of the column to join from the Right Columnarfile
        args[5]= "[L:X,L:Y,L:Z,R:X,R:Y,R:Z]";//Projection from the Left Columnarfile
        args[6]= "6";               //no. of out fields
        args[7]= "20";              // No of buff pages
        args[8]= "true";

        if (args.length != 9)
        {
            System.out.println("The command line invocation must be as follows: \n\t"
                                            + "");
            Runtime.getRuntime().exit(1);
        }

        columnDBName = args[0];
        leftColumnarFileName = args[1];
        rightColumnarFileName = args[3];
        leftColumnNo = Integer.parseInt(args[2]);
        rightColumnNo = Integer.parseInt(args[4]);
        projectionList =  args[5].replace('[', ' ').replace(']', ' ').trim().split(",");
        no_outFields = Integer.parseInt(args[6]);
        mSize = Integer.parseInt(args[7]);
        reCreateIndexes = args[8].equals("true") ? true: false;

        // read an existing DB into BM
        global.SystemDefs sysdef = new global.SystemDefs(columnDBName, 0,mSize, "Clock");
        

        // try read a columnarfiles form DB
        try {
                lcf = new Columnarfile(leftColumnarFileName);
                rcf = new Columnarfile(rightColumnarFileName);
        } catch (Exception ex) {
                System.err.println("Unable to read a columnar files from DB\n\t check if they have been created.\n");
                Runtime.getRuntime().exit(1);
        }

        //Check if the bitmaps exist
        if(reCreateIndexes)
        {
	        lcf.createBitmapForColumn(leftColumnNo - 1);
	        rcf.createBitmapForColumn(rightColumnNo - 1);
        }
        

        sysdef.JavabaseBM.flushAllPages();
        
        FldSpec []  proj = new FldSpec[no_outFields];
        AttrType[] jtype = new AttrType[no_outFields];
        
        
        for(int i = 0 ; i < projectionList.length;i++)
        {
        	String[] str = projectionList[i].trim().split(":");
        	
        	if(str.length != 2)
        	{
                System.err.println("Projection list has incorrect format \"" + args[5] + "\"\n");
                Runtime.getRuntime().exit(1);
        	}
        	
        	if(str[0].equals("L"))
        	{
        		proj[i] = new FldSpec(new RelSpec(RelSpec.outer), lcf.getColumnOffset(str[1]));
        		jtype[i] = lcf.getColumnType(str[1]);
        		
        	}else if(str[0].equals("R"))
        	{
        		proj[i] = new FldSpec(new RelSpec(RelSpec.innerRel), rcf.getColumnOffset(str[1]));
        		jtype[i] = rcf.getColumnType(str[1]);
        	}
        	else
        	{
                System.err.println("Projection list has incorrect format \"" + args[5] + "\"\n");
                Runtime.getRuntime().exit(1);
        	}
        }
        
       
		
        ColumnarBitmapEquiJoins cbitmapjoin = new ColumnarBitmapEquiJoins(
        		lcf.getAttrTypes(),
        		lcf.NumberOfColumns(),
        		lcf.getSizesOfFileds(),
        		rcf.getAttrTypes(),
        		rcf.NumberOfColumns(),
        		rcf.getSizesOfFileds(),
        		mSize,
        		lcf.columnarFileName(),
        		leftColumnNo,
        		rcf.columnarFileName(),
        		rightColumnNo,
        		proj,
        		no_outFields
        		); 
        
        
		System.out.println(sysdef.JavabaseBM.getNumUnpinnedBuffers());
        
        Tuple t = null;
        try {
			while ((t = cbitmapjoin.get_next()) != null) {
				t.print(jtype);
				System.out.println(sysdef.JavabaseBM.getNumUnpinnedBuffers());
			}
			
		}
        catch (Exception e) {
			//System.err.println("" + e);
			e.printStackTrace();
			Runtime.getRuntime().exit(1);
		}
		finally{
			System.out.println(sysdef.JavabaseBM.getNumUnpinnedBuffers());
			cbitmapjoin.close();
		}
       
        
        // print number of processed pages
        System.out.println("\n");
        PCounter.print();
    }
}
